import * as THREE from '../../build/three.module.js';

import { OrbitControls } from '../../jsm/controls/OrbitControls.js';


var container;

var camera, scene, renderer;

init();
animate();

//load customized cube texture
async function loadCubeTextureWithMipmaps() {

  var path = '../../textures/cube/angus/';
  var format = '.jpg';
  var mipmaps = [];
  var maxLevel = 8;

  async function loadCubeTexture( urls ) {

    return new Promise( function ( resolve, reject) {

      new THREE.CubeTextureLoader().load( urls, function ( cubeTexture ) {

        resolve( cubeTexture );

      } );


    } );

  }

  // load mipmaps
  var pendings = [];

  for ( var level = 0; level <= maxLevel; ++ level ) {

    var urls = [];

    for ( var face = 0; face < 6; ++ face ) {

      urls.push( path + 'cube_m0' + level + '_c0' + face + format );

    }

    let mipmapLevel = level;

    pendings.push( loadCubeTexture( urls ).then( function ( cubeTexture ) {

      mipmaps[ mipmapLevel ] = cubeTexture;

    } ) );

  }

  await Promise.all( pendings );

  var customizedCubeTexture = mipmaps.shift();
  customizedCubeTexture.mipmaps = mipmaps;
  customizedCubeTexture.minFilter = THREE.LinearMipMapLinearFilter;
  customizedCubeTexture.magFilter = THREE.LinearFilter;
  customizedCubeTexture.generateMipmaps = false;
  customizedCubeTexture.needsUpdate = true;

  return customizedCubeTexture;

}

function init() {

  container = document.createElement( 'div' );
  document.body.appendChild( container );

  camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 10000 );
  camera.position.z = 500;

  scene = new THREE.Scene();

  loadCubeTextureWithMipmaps().then( function ( cubeTexture ) {

    //model
    var sphere = new THREE.SphereBufferGeometry( 100, 128, 128 );

    //manual mipmaps
    var material = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap: cubeTexture } );
    material.name = 'manual mipmaps';

    var mesh = new THREE.Mesh( sphere, material );
    mesh.position.set( 100, 0, 0 );
    scene.add( mesh );


    //webgl mipmaps
    material = material.clone();
    material.name = 'auto mipmaps';

    var autoCubeTexture = cubeTexture.clone();
    autoCubeTexture.mipmaps = [];
    autoCubeTexture.generateMipmaps = true;
    autoCubeTexture.needsUpdate = true;

    material.envMap = autoCubeTexture;

    mesh = new THREE.Mesh( sphere, material );
    mesh.position.set( - 100, 0, 0 );
    scene.add( mesh );

  } );

  //renderer
  renderer = new THREE.WebGLRenderer( { antialias: true } );
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.setSize( window.innerWidth, window.innerHeight );
  container.appendChild( renderer.domElement );

  //controls
  var controls = new OrbitControls( camera, renderer.domElement );
  controls.minPolarAngle = Math.PI / 4;
  controls.maxPolarAngle = Math.PI / 1.5;

  window.addEventListener( 'resize', onWindowResize, false );

}

function onWindowResize() {

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize( window.innerWidth, window.innerHeight );

}

function animate() {

  requestAnimationFrame( animate );
  renderer.render( scene, camera );

}